/* 
 * SIT, Sistema Integral de Tramites del Ministerio de Minas y Energia
 * Copyright 2010, como se indica en  los tags @author. Revise
 * el archivo  copyright.txt en la lista de desarrollo 
 * 
 * Este NO es un software libre y no puede ser redistribuido y/o modificado
 * bajo ningun termino. El codigo es propietario y solo  puede
 * ser utilizado bajo permiso explicito del Ministerio de Minas y Energia
 * 
 * Este Software no es distribuido publicamente y solo deberia estar
 * ejecutandose en el entorno de desarrollo del Ministerio de Minas y Energia,
 * si por alguna razon este codigo se ejecuta en un entorno diferente estaria 
 * violando la ley de derechos de autor que lo proteje., Al igual que cualquier 
 * uso  del codigo o cualquiera de los componentes del sistema
 * sin autorizacion explicita de los autores.
 * 
 * Si necesita autorizacion para la utilizacion del codigo o parte de el 
 * por favor refierase a la lista de desarrollo del proyecto para contactar 
 * al autor indicado en el tag @author, o comuniquese con 
 * el grupo de arquitectura de software del proyecto.
 */
package co.edu.udistrital.database.dao.api;

import java.io.Serializable;
import java.util.List;

import org.hibernate.criterion.Criterion;

import co.edu.udistrital.database.exceptions.FinderException;

/**
 * Interface para consultas sobre entidad de negocio.
 * 
 * @author <a href="mailto:rcabezas1@gmail.com">Edwin Romero</a>
 * @version $1.0
 * 
 */
@SuppressWarnings("rawtypes")
public interface IFinder {

	/**
	 * No requiere lock, este es el que se usa por defecto.
	 */
	int LOCK_NONE = 0;
	/**
	 * Lock compartido, los objetos fueron leidos desde la base de datos en la
	 * transaccion actual, mas que del cache.
	 */
	int LOCK_READ = 5;
	/**
	 * Un lock de Upgrade. los objetos se obtienen con la sentencia SQL
	 * <tt>select ... for update</tt>.
	 */
	int LOCK_UPGRADE = 10;
	/**
	 * Trata de obtener Lock para Upgrade usando Oracle-style
	 * <tt>select for update nowait</tt>. la semantica es similar a
	 * <tt>UPGRADE</tt>.
	 */
	int LOCK_UPGRADE_NOWAIT = 11;
	/**
	 * Un lock <tt>WRITE</tt> se obtiene cuando un objeto es actualizado o
	 * insertado. Modo no valido para <tt>load()</tt> o <tt>lock()</tt>.
	 */
	int LOCK_WRITE = 12;

	/**
	 * Obtiene el maximo numero de resultados para una consulta.
	 * 
	 * @return Integer numero de resultados
	 */
	Integer getMaxResults();

	/**
	 * Busca todas las entidades cuyo tipo es igual a entityType. La busqueda se
	 * restringe al valor getMaxResults del Servicio configurado en la
	 * inicializaion del servicio.
	 * 
	 * @param entityType
	 *            Tipo de entidad.
	 * @return List resultados encontrados
	 * @throws FinderException
	 *             Si ocurre algun error en el proceso
	 */
	
	List findAll(Class entityType) throws FinderException;

	/**
	 * Busca una entidad cuyo id es el pasado por parametro.
	 * 
	 * @param id
	 *            Identificador de la entidad
	 * @param entityType
	 *            Tipo de entidad
	 * @return entidad de tipo entityClass
	 * @throws FinderException
	 *             Si ocurre algun error en el proceso
	 */
	Object findById(Serializable id, Class entityType) throws FinderException;

	/**
	 * Busca una entidad cuyo id es el pasado por parametro.
	 * 
	 * @param id
	 *            Identificador de la entidad
	 * @param entityType
	 *            Tipo de entidad
	 * @param inicializar
	 *            Inicializa los objetos hijos de la entidad involucrada
	 * @return entidad de tipo entityClass
	 * @throws FinderException
	 *             Si ocurre algun error en el proceso
	 */
	Object findById(Serializable id, Class entityType, boolean inicializar)
			throws FinderException;

	/**
	 * Ejecuta una query cuyo nombre es queryName. Esta query debe estar
	 * configurada en el mapping de hibernate. La busqueda se restringe al valor
	 * getMaxResults del Servicio configurado en la inicializaion del servicio.
	 * 
	 * @param queryName
	 *            Nombre del query a ejecutar
	 * @return List Resultados encontrados
	 * @throws FinderException
	 *             Si ocurre algun error en el proceso
	 */
	List findByNamedQuery(String queryName) throws FinderException;

	/**
	 * Ejecuta una query cuyo nombre es queryName. Esta query debe estar
	 * configurada en el mapping de hibernate. La busqueda se restringe al valor
	 * getMaxResults del Servicio configurado en la inicializaion del servicio.
	 * Se pueden inicializar los hijos pasando el parametro inicializar en true
	 * 
	 * @param queryName
	 *            Nombre del query a ejecutar
	 * @param inicializar
	 *            Si se desean inicializar los objetos hijos
	 * @return List Resultados encontrados
	 * @throws FinderException
	 *             Si ocurre algun error en el proceso
	 */
	List findByNamedQuery(String queryName, boolean inicializar)
			throws FinderException;

	/**
	 * Ejecuta un query reemplazando los parametros en el query.
	 * 
	 * @param squery
	 *            La cadena con el Hibernate query
	 * @param params
	 *            Parametros a reemplazar en el query.
	 * @return List Resultados encontrados
	 * @throws FinderException
	 *             Si ocurre algun error en el proceso
	 */
	List findByQuery(String squery, Object... params) throws FinderException;

	/**
	 * Ejecuta una consulta de acuerdo a los criterios pasados como parametros.
	 * 
	 * @param entityType
	 *            Tipo de entidad sobre la cual consultar.
	 * @param criterion
	 *            Criterios de b�squeda
	 * @return List Resultados encontrados
	 * @throws FinderException
	 *             Si ocurre algun error en el proceso
	 */
	List findByCriteria(Class entityType, final Criterion... criterion)
			throws FinderException;

	/**
	 * Ejecuta una consulta de acuerdo a los criterios pasados como parametros
	 * teniendo en cuenta el maximo de resultados a devolver.
	 * 
	 * @param entityType
	 *            Tipo de entidad.
	 * @param firstResult
	 *            El primer resultado a devolver.
	 * @param maxResults
	 *            Maximo de resultados a devolver..
	 * @param criterion
	 *            Criterios de b�squeda.
	 * @return List Resultados encontrados
	 * @throws FinderException
	 *             Si ocurre algun error en el proceso
	 */
	List findByCriteria(Class entityType, final int firstResult,
			final int maxResults, final Criterion... criterion)
			throws FinderException;

	/**
	 * Ejecuta una consulta de acuerdo a los criterios pasados como parametros
	 * teniendo en cuenta el maximo de resultados a devolver. Adem�s se pasa
	 * como parametro un array de strings con los alias de las tablas con los
	 * cuales hacer join. El alias tiene la siguiente estructura "tabla alias"
	 * 
	 * @param entityType
	 *            Tipo de entidad.
	 * @param firstResult
	 *            El primer resultado a devolver.
	 * @param tables
	 *            Nombres de los tablas para hacer join.
	 * @param maxResults
	 *            Maximo de resultados a devolver.
	 * @param criterion
	 *            Criterios de b�squeda.
	 * @return List Resultados encontrados
	 * @throws FinderException
	 *             Si ocurre algun error en el proceso
	 */
	List findByCriteria(Class entityType, final int firstResult,
			final int maxResults, final String[] alias,
			final Criterion... criterion) throws FinderException;

	/**
	 * Ejecuta una consulta de acuerdo a los criterios pasados como parametros
	 * teniendo en cuenta el maximo de resultados a devolver. Adem�s se pasa
	 * como parametro un array de strings con los alias de las tablas con los
	 * cuales hacer join. El alias tiene la siguiente estructura "tabla alias"
	 * 
	 * @param entityType
	 *            Tipo de entidad.
	 * @param firstResult
	 *            El primer resultado a devolver.
	 * @param tables
	 *            Nombres de los tablas para hacer join.
	 * @param maxResults
	 *            Maximo de resultados a devolver.
	 * @param inicializar
	 *            SI es necesario inicializar el resultado de la lista *
	 * @param criterion
	 *            Criterios de b�squeda.
	 * @return List Resultados encontrados
	 * @throws FinderException
	 *             Si ocurre algun error en el proceso
	 */
	List findByCriteria(Class entityType, final int firstResult,
			final int maxResults, final String[] alias, boolean inicializar,
			final Criterion... criterion) throws FinderException;

	/**
	 * Permite realizar la b�squeda de los criterios incluyendo orderby y
	 * distinct.
	 * 
	 * @param entityType
	 * @param criteria
	 * @return
	 * @throws FinderException
	 */
	List findByCriteria(Class entityType, final String orderBy,
			final boolean distinct, Criterion... criterion)
			throws FinderException;

	/**
	 * Ejecuta una query cuyo nombre es queryName y la cual posee bindings "?".
	 * Esta query debe estar configurada en el mapping de hibernate.<br>
	 * 
	 * @param queryName
	 * @param values
	 *            valores correspondientes a los bindings.
	 * 
	 * @return Collection
	 * 
	 * @throws FinderException
	 */
	public List findByNamedQuery(String queryName, Object... params)
			throws FinderException;

	List findByNamedQuery(String queryName, boolean inicializar,
			Object... params) throws FinderException;

	public List findByNativeQuery(String query, Object... params)
			throws FinderException;

	/**
	 * Ejecuta un query nativo a la base de datos
	 * 
	 * @param query
	 *            Query a ejecutar
	 * @param params
	 *            Parametros del query
	 * @throws FinderException
	 *             Si ocurre algun error en el proceso
	 */
	public void executeNativeQuery(String query, Object... params)
			throws FinderException;

	public void refresh(Object o);

	public void iniatialize(Object o);

}
